﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Smart
{
    public class Synchronization
    {
        enum SyncParam : byte
        {
            Barkod,
            CariAdres,
            Cari,
            Matris,
            SrmMerkezleri,
            Depo,
            Doviz,
            Stok,
            CariBakiye,
            Envanter
        }

        Dictionary<SyncParam, DateTime> syncTime = new Dictionary<SyncParam, DateTime>();

        void AddSyncTime(SyncParam islem, DateTime value)
        {
            if (syncTime.ContainsKey(islem))
                syncTime[islem] = value;
            else
                syncTime.Add(islem, value);
        }
        string syncTimetoString(SyncParam islem, DateTime val)
        {
            if (syncTime.ContainsKey(islem))
                return string.Format("{0}-{1}-{2}", syncTime[islem].Year, syncTime[islem].Month, syncTime[islem].Day);
            else
                return "1900-01-01";
        }
        DateTime lastSyncTime(SyncParam islem)
        {
            if (syncTime.ContainsKey(islem))
                return syncTime[islem];
            else
                return new DateTime(1900, 1, 1);
        }
        void sysdateLoad(string fileName)
        {
            if (File.Exists(fileName))
            {
                using (StreamReader sr = new StreamReader(fileName))
                {
                    while (sr.Peek() > -1)
                    {
                        string[] line = sr.ReadLine().Split(';');
                        string[] tarih = line[1].Split('-');
                        AddSyncTime((SyncParam)Enum.Parse(typeof(SyncParam), line[0], true), new DateTime(int.Parse(tarih[0]),
                            int.Parse(tarih[1]), int.Parse(tarih[2])));
                    }
                    sr.Close();
                }
            }
        }
        void sysdateSave(string fileName)
        {
            using (StreamWriter sw = new StreamWriter(fileName, false))
            {
                sw.WriteLine(String.Format("{0};{1}", "Barkod", syncTimetoString(SyncParam.Barkod, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Cari", syncTimetoString(SyncParam.Cari, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "CariAdres", syncTimetoString(SyncParam.CariAdres, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Matris", syncTimetoString(SyncParam.Matris, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "SrmMerkezleri", syncTimetoString(SyncParam.SrmMerkezleri, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Depo", syncTimetoString(SyncParam.Depo, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Doviz", syncTimetoString(SyncParam.Doviz, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Stok", syncTimetoString(SyncParam.Stok, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "CariBakiye", syncTimetoString(SyncParam.CariBakiye, new DateTime(1900, 1, 1))));
                sw.WriteLine(String.Format("{0};{1}", "Envanter", syncTimetoString(SyncParam.Envanter, new DateTime(1900, 1, 1))));
                sw.Close();
            }
        }
        DateTime getServiceTime()
        {
            string[] records = BackOffice.Get.getServiceTime()[0].Split('-');
            if (records.Length > 0)
                return new DateTime(int.Parse(records[0]), int.Parse(records[1]), int.Parse(records[2]));
            else
                return new DateTime(1900, 1, 1);
        }

        #region Ctor
        private static Synchronization _instance = null;
        private Synchronization() { }
        public static Synchronization Get
        {
            get
            {
                if (_instance == null)
                    _instance = new Synchronization();
                return _instance;
            }
        }
        #endregion

        public void StartSync()
        {
            sysdateLoad(Methods.StartupPath() + "\\sync.txt");
            SiparisGonder();
            TahsilatGonder();

            DateTime tarih = _instance.getServiceTime();
            string[] row = BackOffice.Get.BarkodList(lastSyncTime(SyncParam.Barkod));
            SqlCeClient.Get.importAllRows("TBL_BARKOD", row);
            AddSyncTime(SyncParam.Barkod, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.CariList(lastSyncTime(SyncParam.Cari));
            SqlCeClient.Get.importAllRows("TBL_CARI", row);
            AddSyncTime(SyncParam.Cari, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.CariAdresList(lastSyncTime(SyncParam.CariAdres));
            SqlCeClient.Get.importAllRows("TBL_ADRES", row);
            AddSyncTime(SyncParam.CariAdres, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.DepoList();
            SqlCeClient.Get.importAllRows("TBL_DEPO", row);
            AddSyncTime(SyncParam.Depo, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.DovizKurlari(DateTime.Now);
            SqlCeClient.Get.importAllRows("TBL_DOVIZ", row);

            row = BackOffice.Get.IskontoMatris(lastSyncTime(SyncParam.Matris));
            SqlCeClient.Get.importAllRows("TBL_MATRIS", row);
            AddSyncTime(SyncParam.Matris, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.StokList(lastSyncTime(SyncParam.Stok));
            SqlCeClient.Get.importAllRows("TBL_STOK", row);
            AddSyncTime(SyncParam.Stok, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            row = BackOffice.Get.SrmList();
            SqlCeClient.Get.importAllRows("TBL_SRM", row);
            AddSyncTime(SyncParam.SrmMerkezleri, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            string[] srmList = new string[10];
            for (int i = 0; i < srmList.Length; i++)
            {
                srmList[i] = string.Empty;
            }
            int x = 0;
            foreach (string item in row.Take(10))
            {
                srmList[x] = item.Split('Æ')[1];
                x++;
            }

            row = BackOffice.Get.CariBakiyeList(lastSyncTime(SyncParam.CariBakiye), srmList);
            SqlCeClient.Get.importAllRows("TBL_CARIBAKIYE", row);
            AddSyncTime(SyncParam.CariBakiye, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");

            foreach (int depo in Program.Session.KullanilabilirDepolar())
            {
                row = BackOffice.Get.EnvanterList(depo, lastSyncTime(SyncParam.Envanter));
                SqlCeClient.Get.importAllRows("TBL_ENVANTER", row);
            }
            AddSyncTime(SyncParam.Envanter, tarih);
            sysdateSave(Methods.StartupPath() + "\\sync.txt");


        }

        #region Evrak Gönderimleri
        private void SiparisGonder()
        {
            using (Query q = new Query(ProgramTipleri.SqlCe))
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("SELECT     evr_seri, evr_sira, evr_tarih, evr_belgeno, evr_saticikod, evr_carikod, evr_cikis_depo, evr_srm_merkezi,evr_vade FROM TBL_EVRAK ");
                sb.Append(" WHERE     (evr_gonderildi = 0) AND (evr_cins = 0) ");
                sb.Append(" GROUP BY evr_seri, evr_sira, evr_tarih, evr_belgeno, evr_saticikod, evr_carikod, evr_cikis_depo, evr_srm_merkezi,evr_vade ");
                q.Add(sb.ToString());

                var evraklar = q.ToList(new { seri = "", sira = 0, tarih = DateTime.Now, belge = "", satici = "", cari = "", depo = 0, srm = "", vade = 0m });
                string[] header;
                string[] detail;

                if (evraklar.Count > 0)
                {
                    foreach (var evr in evraklar)
                    {
                        header = new string[13];
                        header[1] = "0";
                        header[2] = "0";
                        header[3] = evr.seri;
                        header[4] = evr.sira.ToString();
                        header[5] = evr.tarih.ToSqlString(); ;
                        header[6] = evr.belge;
                        header[7] = evr.satici;
                        header[8] = evr.cari;
                        header[9] = evr.depo.ToString();
                        header[10] = evr.srm;
                        header[11] = evr.vade.ToString();
                        header[12] = Program.Session[Settings.MikroKullanici].ToString();
                        detail = SiparisSatirlari(evr.seri, evr.sira);
                        try
                        {
                            bool sonuc = BackOffice.Get.EvrakEkle(header, detail);
                            if (sonuc)
                            {
                                AktarildiDuzelt(evr.seri, evr.sira, true);
                            }
                        }
                        catch (Exception ex)
                        {
                            ExceptionHandling.Hand(ex);
                        }
                    }
                }
            }
        }
        private string[] SiparisSatirlari(string seri, int sira)
        {
            List<string> liste = new List<string>();
            using (Query q = new Query(ProgramTipleri.SqlCe))
            {
                q.Add(string.Format("SELECT     evr_stokkod, evr_fiyat, evr_miktar, evr_tutar, evr_isk1_tutar, evr_isk2_tutar, evr_isk3_tutar, evr_isk4_tutar, evr_isk5_tutar, evr_vergi_id, evr_vergi_tutar,evr_aciklama FROM TBL_EVRAK WHERE (evr_seri = '{0}') AND (evr_sira = {1}) AND (evr_cins = 0)", seri, sira));
                var satirlar = q.ToList(new { stok = "", fiyat = 0m, miktar = 0m, tutar = 0m, isk1 = 0m, isk2 = 0m, isk3 = 0m, isk4 = 0m, isk5 = 0m, kdvno = 0m, kdvtutar = 0m, aciklama = "" });
                foreach (var satir in satirlar)
                {
                    liste.Add(string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10};{11}",
                        satir.stok, satir.fiyat.ToString(), satir.miktar.ToString(), satir.tutar.ToString(),
                        satir.isk1.ToString(), satir.isk2.ToString(), satir.isk3.ToString(), satir.isk4.ToString(),
                        satir.isk5.ToString(), satir.kdvno.ToString(), satir.kdvtutar.ToString(), satir.aciklama.ToString()));

                }
            }
            return liste.ToArray();
        }
        private void AktarildiDuzelt(string seri, int sira, bool siparis)
        {
            using (Query q = new Query(ProgramTipleri.SqlCe))
            {
                if (siparis)
                {
                    q.Add(string.Format("UPDATE    TBL_EVRAK  SET evr_gonderildi = 1  WHERE     (evr_seri = '{0}') AND (evr_sira = {1})", seri, sira));
                }
                else
                {
                    q.Add(string.Format("UPDATE    TBL_TAHSILAT  SET ths_gonderildi = 1  WHERE     (ths_seri = '{0}') AND (ths_sira = {1})", seri, sira));
                }
                q.Exec();
            }
        }
        private void TahsilatGonder()
        {
            using (Query q = new Query(ProgramTipleri.SqlCe))
            {
                q.Add("SELECT ths_tip,ths_seri,ths_sira,ths_satir,ths_belgeno,ths_tarih,ths_vade_tarih,ths_saticikod,ths_carikod,ths_srm_merkezi,ths_referans_no,ths_ceksenet_no,ths_meblag,ths_aciklama FROM TBL_TAHSILAT WHERE     (ths_gonderildi = 0) ");

                var evraklar = q.ToList(new { tip = 0, seri = "", sira = 0, satir = 0, belgeno = "", tarih = DateTime.Now, vade = DateTime.Now, satici = "", cari = "", srm = "", refno = "", ceksenetno = "", meblag = 0m, aciklama = "" });
                string[] Lines;

                if (evraklar.Count > 0)
                {
                    foreach (var evr in evraklar)
                    {
                        Lines = new string[19];
                        Lines[0] = evr.tip.ToString();
                        Lines[1] = evr.seri;
                        Lines[2] = evr.sira.ToString();
                        Lines[3] = evr.satir.ToString();
                        Lines[4] = evr.belgeno;
                        Lines[5] = evr.tarih.ToSqlString();
                        Lines[6] = evr.vade.ToSqlString();
                        Lines[7] = evr.satici;
                        Lines[8] = evr.cari;
                        Lines[9] = evr.srm;
                        Lines[10] = evr.refno;
                        Lines[11] = evr.ceksenetno;
                        Lines[12] = evr.meblag.ToString();
                        Lines[13] = evr.aciklama;
                        Lines[14] = Program.Session[Settings.TahsilatNakitKasaKodu].ToString();
                        Lines[15] = Program.Session[Settings.TahsilatCekKasaKodu].ToString();
                        Lines[16] = Program.Session[Settings.TahsilatSenetKasaKodu].ToString();
                        Lines[17] = Program.Session[Settings.TahsilatKrediKartiBankaKodu].ToString();
                        Lines[18] = Program.Session.VarsayilanDepo().ToString();

                        try
                        {
                            bool sonuc = BackOffice.Get.TahsilatEkle(Lines);
                            if (sonuc)
                            {
                                AktarildiDuzelt(evr.seri, evr.sira, false);
                            }
                        }
                        catch (Exception ex)
                        {
                            ExceptionHandling.Hand(ex);
                        }
                    }
                }
            }
        }
        #endregion
    }
}
